import { defineStore } from 'pinia'
import { constantRoutes } from '@/router'
import { getUserMenuTreeByUserId, MenuTree } from '@/api/system/menu'
import Layout from '@/layout/index.vue'
import { AppRouteRecordRaw, RouteMeta } from '@/types/router'
import { defineAsyncComponent } from 'vue'

interface IPermissionState {
  routes: AppRouteRecordRaw[]
  addRoutes: AppRouteRecordRaw[]
  loadingRoutes: boolean
  loadError: string | null
}

interface MenuTreeResponse {
  menuTree: MenuTree[]
}

var modules = import.meta.glob('../views/**/**/*.vue')

export const getRoutesFromMenuTree = (menuTree: MenuTree[]): AppRouteRecordRaw[] => {
  const routes: AppRouteRecordRaw[] = []
  menuTree.forEach((menu) => {
    // 添加过滤逻辑，排除特殊路由
    if (menu.path === '/login' || menu.path === '/404' || menu.path === '/401') {
      return
    }
    console.log('当前处理的菜单项:', {
      path: menu.path,
      component: menu.component,
      title: menu.title,
      hasChildren: menu.children?.length > 0,
      parentMenu: !menu.component || menu.component === 'Layout'
    })

    // 处理子菜单
    const children = menu.children && menu.children.length > 0 ? getRoutesFromMenuTree(menu.children) : undefined
    // console.log('Processing----------- children:', JSON.stringify(children))

    const meta: RouteMeta = {
      title: menu.title,
      icon: menu.icon,
      hidden: menu.hidden === 1,  // 1 表示隐藏，其他值表示显示
      noCache: menu.noCache === 1,  // 1 表示不缓存，其他值表示缓存
      breadcrumb: menu.breadcrumb === 1,  // 1 表示可见，其他值表示隐藏
      alwaysShow: menu.alwaysShow === 1 || (children && children.length > 0),  // 1 表示忽略，其他值表示不忽略
      activeMenu: menu.activeMenu
    }

    // 处理路径
    let path = menu.path
    if (menu.component === 'Layout') {
      // 父级菜单路径必须以 / 开头
      if (!path.startsWith('/')) {
        path = '/' + path
      }
    } else {
      // 子菜单路径不要以 / 开头
      if (path.startsWith('/')) {
        path = path.substring(1)
      }
    }

    // 处理组件
    let component
    if (menu.component === 'Layout') {
      component = Layout
    } else {
      if (!validateComponentPath(menu.component)) {
        console.warn(`Invalid component path: ${menu.component}`)
        return
      }
      component = loadComponent(menu.component)
    }

    const route = {
      path: path,
      name: menu.name,
      component: component,
      redirect: menu.redirect || undefined,
      children: children,
      meta: {
        ...meta,
        alwaysShow: menu.component === 'Layout' || (children && children.length > 0)
      }
    } as AppRouteRecordRaw

    // routes.push(route)
    if (component || (children && children.length > 0)) {
      routes.push(route)
    }
  })
  console.log('Finally Generated routes:', routes)
  return routes
}

export const loadComponent = (component?: string) => {
  if (!component) {
    return undefined
  }
  if (component === 'Layout') {
    return Layout
  }

  try {
    // 移除开头的斜杠并统一处理路径
    let componentPath = component.startsWith('/') ? component.slice(1) : component

    // 统一路径格式：移除可能的 index 后缀
    componentPath = componentPath.replace(/\/index$/, '')

    console.log('Loading component path:', componentPath)

    // 使用 defineAsyncComponent 来加载组件
    return defineAsyncComponent(() => modules[`../views/${componentPath}/index.vue`]())
  } catch (err) {
    console.error(`Failed to load component: ${component}`, err)
    return undefined
  }
}

const validateComponentPath = (path: string): boolean => {
  // 基本路径验证
  if (!path) return false

  // 安全性检查：防止路径穿越
  if (path.includes('..') || path.includes('\\')) return false

  // 格式检查：只允许字母、数字、下划线、斜杠
  return /^[a-zA-Z0-9_/\-]+$/.test(path)
}

export const usePermissionStore = defineStore('permission', {
  state: (): IPermissionState => ({
    routes: [],
    addRoutes: [],
    loadingRoutes: false,
    loadError: null
  }),
  getters: {
    getRoutes(): AppRouteRecordRaw[] {
      return this.routes
    },
    getAddRoutes(): AppRouteRecordRaw[] {
      return this.addRoutes
    }
  },
  actions: {
    setRoutes(routes: AppRouteRecordRaw[]) {
      this.addRoutes = routes
      this.routes = constantRoutes.concat(routes)
    },
    resetRoutes() {
      this.routes = []
      this.addRoutes = []
    },
    async generateRoutes(userinfo: { id: number; roles: string[] }) {
      this.loadingRoutes = true
      this.loadError = null

      try {
        const { data } = await getUserMenuTreeByUserId(userinfo.id)
        if (!data) {
          throw new Error('Menu tree data is null')
        }

        const menuTree = Array.isArray(data) ? data : (data as MenuTreeResponse).menuTree
        const accessedRoutes = getRoutesFromMenuTree(menuTree)

        this.setRoutes(accessedRoutes)
        return accessedRoutes
      } catch (error) {
        this.loadError = error.message
        throw error
      } finally {
        this.loadingRoutes = false
      }
    }
  }
})
